package com.baizhi.mall.aspect;

import com.baizhi.mall.annotation.LogAnnotation;
import com.baizhi.mall.entity.mysql.LogDO;
import com.baizhi.mall.service.impl.LogServiceImpl;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;

@Component
@Aspect
public class LogAspect {
    @Autowired
    private LogServiceImpl logService;

    private Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Pointcut("@annotation(com.baizhi.mall.annotation.LogAnnotation)")
    public void pointcut(){}

    @Around("pointcut()")
    public Object logAfter(ProceedingJoinPoint joinPoint) throws Throwable {
        //方法开始时间
        Date start = new Date();
        System.out.println("start = " + start);
        //执行原始方法
        Object proceed = joinPoint.proceed();
        //获取用户名
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        String username = (String)requestAttributes.getAttribute("username",RequestAttributes.SCOPE_SESSION);
        //获取用户名2
        /*UserDetails userDetails = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String username = userDetails.getUsername();*/
        System.out.println("username = " + username);
        //获取系统时间
        Date end = new Date();
        System.out.println("end = " + end);
        //获取用户登录的ip
        ServletRequestAttributes httpRequestAttributes = (ServletRequestAttributes)requestAttributes;
        HttpServletRequest request = httpRequestAttributes.getRequest();
        String ip = request.getRemoteHost();
        System.out.println("ip = " + ip);
        //获取操作类型和操作内容
        Signature signature = joinPoint.getSignature();
        String methodName = signature.getName();
        System.out.println("methodName = " + methodName);

        //获取方法参数列表
        MethodSignature methodSignature = (MethodSignature)signature;
        Class[] parameterTypes = methodSignature.getParameterTypes();
        System.out.println("parameterTypes = " + Arrays.toString(parameterTypes));

        //获取方法对象
        Method method = joinPoint.getTarget().getClass().getDeclaredMethod(methodName,parameterTypes);
        System.out.println("method = " + method);

        //从方法上获取注解
        LogAnnotation annotation = method.getDeclaredAnnotation(LogAnnotation.class);
        System.out.println("annotation = " + annotation);
        String type = annotation.type();
        String content = annotation.content();

        //将以上数据封装为Log实体对象，并调用LogService的addLog方法
        LogDO logDO = new LogDO(null,username+" ",type,methodName,Arrays.toString(parameterTypes),
                (end.getTime()-start.getTime())+" ",ip,start);
        logService.save(logDO);
        //返回结果
        return proceed;
    }
}
